package com.sinvo.oa.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sinvo.oa.entity.model.system.SysRoleMenu;
import com.sinvo.oa.entity.vo.system.SysRoleQueryVo;
import com.sinvo.oa.exception.CustomException;
import com.sinvo.oa.mapper.SysRoleMapper;
import com.sinvo.oa.mapper.SysRoleMenuMapper;
import com.sinvo.oa.mapper.SysUserRoleMapper;
import com.sinvo.oa.result.ResultCode;
import com.sinvo.oa.service.SysRoleMenuService;
import com.sinvo.oa.service.SysRoleService;
import com.sinvo.oa.entity.model.system.SysRole;
import com.sinvo.oa.entity.model.system.SysUserRole;
import com.sinvo.oa.entity.vo.system.AssignRoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description SysRoleService实现类
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;


    @Override
    public Page<SysRole> findRoleByPage(Page<SysRole> page, SysRoleQueryVo sysRoleQueryVo) {
        //封装条件，判断roleName是否为空
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        String roleName = sysRoleQueryVo.getRoleName();
        if (!StringUtils.isEmpty(roleName)) {
            //不为空则封装 like模糊查询
            wrapper.like(SysRole::getRoleName, roleName);
        }
        //调用方法查询
        Page<SysRole> pageModel = this.page(page, wrapper);
        return pageModel;
    }

    @Override
    public void saveRole(SysRole sysRole) {
        //构造条件 roleCode 不能重复
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleCode, sysRole.getRoleCode());
        int count = this.count(queryWrapper);
        if (count > 0) {
            throw new CustomException(ResultCode.DATA_ERROR.getCode(), "角色编码重复");
        }
        //插入成功
        boolean success = this.save(sysRole);
        if (!success) {
            throw new CustomException(ResultCode.SERVICE_ERROR.getCode(), "新增失败，请重试");
        }
    }

    @Override
    public void updateRole(SysRole sysRole) {
        //构造条件 roleCode 不能重复
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleCode, sysRole.getRoleCode());
        SysRole one = this.getOne(queryWrapper);
        if (one != null && one.getId() != sysRole.getId()) {
            throw new CustomException(ResultCode.DATA_ERROR.getCode(), "角色编码重复");
        }
        boolean success = this.updateById(sysRole);
        if (!success) {
            throw new CustomException(ResultCode.SERVICE_ERROR.getCode(), "更新失败，请重试");
        }
    }

    @Transactional
    @Override
    public boolean removeRole(Long id) {
        this.removeById(id);
        LambdaQueryWrapper<SysRoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleMenu::getRoleId,id);
        sysRoleMenuMapper.delete(queryWrapper);
        return true;
    }

    //根据userId查询其角色
    @Override
    public Map<String, Object> findRoleByUserId(Long userId) {
        //所有的角色
        List<SysRole> allRolesList = this.list();
        //该用户已分配的角色
        List<SysRole> assignedRoleList = sysRoleMapper.queryAssignedRoleByUserId(userId);
        //封装
        Map<String, Object> roleMap = new HashMap<>();
        roleMap.put("assignedRoleList", assignedRoleList);
        roleMap.put("allRolesList", allRolesList);
        return roleMap;
    }

    //分配角色
    @Transactional
    @Override
    public boolean assignRoles(AssignRoleVo assignRoleVo) {
        //删除原有角色
        LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUserRole::getUserId, assignRoleVo.getUserId());
        sysUserRoleMapper.delete(queryWrapper);
        //重新分配
        List<SysUserRole> assignRoleList = assignRoleVo.getRoleIdList().stream().map((id) -> {
            SysUserRole sysUserRole = new SysUserRole();
            sysUserRole.setUserId(assignRoleVo.getUserId());
            sysUserRole.setRoleId(id);
            return sysUserRole;
        }).collect(Collectors.toList());
        sysUserRoleMapper.saveUserRoleByBatch(assignRoleList);
        return true;
    }
}
